package ig.util.ejb;

import ig.util.TripleDESEncryption;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.naming.NamingException;

/**
 * Define caracteristicas y metodos utiles que pueden llegar a ser utilizados en los
 * beans de entidad y session que conformen la aplicacion.
 * @author lfgarcia
 */

public class IGBean {

    private static Map<String,Connection> mConn = new HashMap<String,Connection>();
    
    /**
     * Retorna una conexion segun parametros
     * 
     * @param URL
     * @param usuario
     * @param password
     * @param JNDI
     * @return
     * @throws SQLException 
     */
    public static Connection getNewConexionEnBaseDeDatos(String URL,String usuario,String password, Long id) throws SQLException {
        String KEY = id+"";
        //Esto es para que los tipos de conexiones ODBC siempre se carguen
        boolean isOdbc = URL.startsWith("jdbc:odbc:");
        if( isOdbc || ( mConn.containsKey(KEY) && !mConn.get(KEY).isClosed()) ){
            DriverManager.setLoginTimeout(60);
            Connection connection =DriverManager.getConnection(URL.trim(), usuario.trim(), password.trim());
            if( !isOdbc ){
                mConn.put(KEY,connection);
            }
            return connection;
        }else{
            return mConn.get(KEY);
        }
    }
    
	protected Connection conn = null;
        protected Connection conn1 = null;
	protected PreparedStatement pstmt1 = null;
	protected PreparedStatement pstmt2 = null;
	protected PreparedStatement pstmt3 = null;
	protected PreparedStatement pstmt4 = null;
	protected PreparedStatement pstmt5 = null;

        public static final String METRICA_DB_NAME = "METRICADB";
        public static final String METRICA_DA_NAME = "METRICADA";
        public static final String METRICA_DW_NAME = "METRICADW";
        
        private static Connection METRICA_DB = null;
        private static Connection METRICA_DA = null;
        private static Connection METRICA_DW = null;
        
        protected void closeAll(){
            //try {conn.close();} catch (Exception e) {}
            //try {conn1.close();} catch (Exception e) {}
            try {pstmt1.close();} catch (Exception e) {}
            try {pstmt2.close();} catch (Exception e) {}
            try {pstmt3.close();} catch (Exception e) {}
            try {pstmt4.close();} catch (Exception e) {}
            try {pstmt5.close();} catch (Exception e) {}
        }

        /**
         * Retorna la conexion a metricada
         * @return
         * @throws SQLException 
         */
        public static Connection getMetricaDA() throws SQLException {
            if(METRICA_DA == null || METRICA_DA.isClosed()){
                System.out.println("*** SOLICITANDO CONEXION A METRICADA");
                METRICA_DA = getConexion(METRICA_DA_NAME);
            }
            return METRICA_DA;
        }
        /**
         * Retorna la conexion a metricada
         * @return
         * @throws SQLException 
         */
        public static Connection getMetricaDW() throws SQLException {
            if(METRICA_DW == null || METRICA_DW.isClosed()){
                System.out.println("*** SOLICITANDO CONEXION A METRICADW");
                METRICA_DW = getConexion(METRICA_DW_NAME);
            }
            return METRICA_DW;
        }
        
        /**
         * Retorna la conexion a metricadb
         * @return
         * @throws SQLException 
         */
        public static Connection getMetricaDB() throws SQLException {
            if(METRICA_DB == null || METRICA_DB.isClosed()){
                System.out.println("*** SOLICITANDO CONEXION A METRICADB");
                METRICA_DB = getConexion(METRICA_DB_NAME);
            }
            return METRICA_DB;
        }
        
        /**
         * Cierra las otras conexiones
         */
        public static void closeConnectionOtras(){
            Iterator<String> iterator = mConn.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                try {
                    mConn.remove(key).close();
                } catch (Exception e) {
                }
            }
        }
        /**
         * Cierra todas la conexiones a metrica
         */
        public static void closeConnectionMetrica(){
            try {
                METRICA_DA.close();
                METRICA_DA=null;
            } catch (Exception e) {}
            try {
                METRICA_DB.close();
                METRICA_DB=null;
            } catch (Exception e) {}
            try {
                METRICA_DW.close();
                METRICA_DW=null;
            } catch (Exception e) {}
            
        }
        /**
         * Metodo que crea una conexion a un datasoirce definido
         * @param datasource
         * @return
         * @throws SQLException 
         */
	private static Connection getConexion(String datasource) throws SQLException{
                FileInputStream fis = null;
                try {
                    Properties properties = new Properties();
                    properties.load(fis = new FileInputStream(new File("server/"+datasource+"-DS.properties")));
                    Class.forName(properties.getProperty("driver"));
                    
                    try {
                        String _clave = TripleDESEncryption.decrypt(properties.getProperty("password"), "informaciongerencial.com");
                        properties.put("password", _clave);
                    } catch (Exception e) {
                        
                    }
                    return DriverManager.getConnection(properties.getProperty("url"), properties);    
                } catch (SQLException e) {
                    System.out.println(" DataSource no encontrado : METRICADB :"+e.toString());
                    throw e;
                } catch (Exception e) {
                    System.out.println(" DataSource no encontrado : METRICADB :"+e.toString());
                    throw new SQLException(e);
                }finally{
                    try { fis.close(); } catch (Exception e) {}
                }
	}
        
        /**
         * Metodo que crea un conexion segun nombre del dataSource
         * @param datasource
         * @return
         * @throws NamingException
         * @throws SQLException 
         */
	public static Connection getNewConexion(String datasource) throws NamingException, SQLException{
                return getConexion(datasource);
	}
}

